#!/usr/bin/env python
# -*- coding: utf-8 -*-

import datetime
from Atm.core import auth
from Atm.core.auth import login_required
from Atm.core import accounts
from Atm.core import transaction
from Atm.conf import config
from Atm.core.bill import bill_check
from Atm.core.logger import logger

user_data = {
    'account_id': None,
    'is_authenticated': False,
    'account_data': None
}

def pay(amount):
    '''
    购物消费扣款
    :param acc_data:
    :return:
    '''
    acc_data = auth.acc_login(user_data)
    if user_data['is_authenticated']:
        user_data['account_data'] = acc_data
        if acc_data['user_type'] == 0:
            if amount > 0:
                new_balance = transaction.make_transaction(user_data['account_data'], 'consume', amount)
                if new_balance:
                    print('已支付: ￥%s, 新的余额为: ￥%s' % (amount,new_balance['balance']))
                    return True
        else:
            print('您输入的用户名或密码错误...')

@login_required
def account_info(acc_data):
    '''
    查看账户信息
    :param acc_data:
    :return:
    '''
    account_data = acc_data['account_data']
    acc_info = '''---------- {account} 账户信息 ----------
       账号:     {account}
       额度:     ￥{credit}
       余额:     ￥{balance}
       账单日:    每月{pay_day}日
       还款日:    每月{repay_day}日
       过期时间:  {expire}
    '''.format(account=account_data['id'],credit=account_data['credit'],balance=account_data['balance'],
               pay_day=account_data['pay_day'],repay_day=account_data['repay_day'],expire=account_data['expire_date'])
    print(acc_info)

@login_required
def repay(acc_data):
    '''
    打印当前余额,并提示还款
    :param acc_data:
    :return:
    '''
    account_data = accounts.load_current_balance(acc_data['account_id'])

    current_balance = '''---------- {account} 余额信息 ----------
    额度:     ￥{credit}
    余额:     ￥{balance}
    '''.format(account=account_data['id'],credit=account_data['credit'],balance=account_data['balance'])
    print(current_balance)
    while True:
        repay_amount = input('[q退出]请输入要还的金额:').strip()
        if len(repay_amount) > 0:
            if repay_amount == 'q':break
            try:
                repay_amount = float(repay_amount)
                if account_data['credit']/2 > account_data['withdraw']: # 判断额度的50%是否大于取现额度
                    if account_data['credit']/2 < (account_data['withdraw'] + repay_amount): # 判断还款后加取现额度是否大于总额度的50%
                        account_data['withdraw'] = account_data['credit']/2
                    else:
                        account_data['withdraw'] = account_data['withdraw'] + repay_amount
                new_balance = transaction.make_transaction(account_data, 'repay', repay_amount)  # 还款操作
                user_data['account_data']['balance'] = new_balance['balance']   # 还款后及时更新余额信息
                if new_balance:
                    print('还款成功,新的余额为: ￥%s' % new_balance['balance'])
            except ValueError:
                print('输入的金额错误,请输入数字...')

@login_required
def withdraw(acc_data):
    '''
    取款函数
    :param acc_data:
    :return:
    '''
    account_data = accounts.load_current_balance(acc_data['account_id'])
    current_balance = '''---------- {account} 余额信息 ----------
        额度:     ￥{credit}
        余额:     ￥{balance}
        取现额度:  ￥{withdraw}
        '''.format(account=account_data['id'], credit=account_data['credit'],
                   balance=account_data['balance'], withdraw=account_data['withdraw'])
    print(current_balance)
    while True:
        withdraw_amount = input('[q退出]请输入取款金额:').strip()
        if len(withdraw_amount) > 0:
            if withdraw_amount == 'q':break
            try:
                withdraw_amount = float(withdraw_amount)
                if account_data['withdraw'] > withdraw_amount and account_data['balance'] > withdraw_amount: #判断取现金额是否小于总取现额度和余额
                    account_data['withdraw'] = account_data['withdraw'] - withdraw_amount   # 取现额度减取现金额
                    new_balance = transaction.make_transaction(account_data, 'withdraw', withdraw_amount)
                    user_data['account_data']['balance'] = new_balance['balance']
                    if new_balance:
                        print('取现成功, 取现金额为: ￥%s' % withdraw_amount)
                else:
                    print('你的额度不足...')
            except ValueError:
                print('输入的金额错误,请输入数字...')

@login_required
def transfer(acc_data):
    '''
    转账函数
    :param acc_data:
    :return:
    '''
    account_data = accounts.load_current_balance(acc_data['account_id'])
    current_balance = '''---------- {account} 余额信息 ----------
        额度:     ￥{credit}
        余额:     ￥{balance}
        '''.format(account=account_data['id'], credit=account_data['credit'], balance=account_data['balance'])
    print(current_balance)
    while True:
        payee = input('[q退出]请输入收款人账号:').strip()
        if len(payee) > 0:
            if payee == 'q':break
            if payee != str(account_data['id']):     # 判断是否转账给自己
                account = auth.acc_check(payee)
                if account and account['user_type'] == 0:   # 判断是否为普通用户
                    transfer_amount = input('[q退出]请输入转账金额:').strip()
                    if len(transfer_amount) > 0:
                        if transfer_amount == 'q':break
                        try:
                            transfer_amount = float(transfer_amount)
                            if account_data['balance'] > transfer_amount:   # 判断余额是否大于转账金额
                                if (account_data['balance'] - transfer_amount) < account_data['withdraw']:  # 判断转账后余额是否小于取现额度
                                    interest = config.TRANSACTION_TYPE['transfer']['interest'] * transfer_amount
                                    account_data['withdraw'] = account_data['balance'] - transfer_amount - interest # 调整取现额度
                                new_balance = transaction.make_transaction(account_data, 'transfer', transfer_amount) # 转账后减余额
                                other_balance = transaction.make_transaction(account, 'receipt', transfer_amount)   # 收到转账金额加余额
                                user_data['account_data']['balance'] = new_balance['balance']
                                user_data['account_data']['withdraw'] = new_balance['balance']
                                if new_balance and other_balance:
                                    print('转账成功,新的余额为: ￥%s' % new_balance['balance'])
                            else:
                                print('你的余额不足...')
                        except ValueError:
                            print('输入的金额错误,请输入数字...')
                else:
                    print('你输入的账号不存在...')
            else:
                print('不能转账给自己...')
#========================================================================
def query_user_info():
    '''
    查询用户信息
    :return:
    '''
    account = input('请输入要查询的账户ID:').strip()
    account_data = auth.acc_check(account)
    if account_data['status'] == 0:     # 判断账户状态
        status = '正常'
    elif account_data['status'] == 1:
        status = '冻结'
    elif account_data['status'] == 2:
        status = '注销'
    if account_data:
        if account_data['user_type'] == 0:
            print('''     ------ %s 用户信息 ------
            信用额度:   ￥%s
            可用额度:   ￥%s
            账单日:     每月%s日
            还款日:     每月%s日
            卡片状态:   %s
            开卡时间:   %s
            过期时间:   %s
            ''' % (account_data['id'],account_data['credit'],account_data['balance'],str(account_data['pay_day']),
                   str(account_data['repay_day']),status,account_data['enroll_date'],account_data['expire_date']))
        else:
            print('只允许查普通用户信息...')
    else:
        print('您查询的账户[%s]不存在...' % account)

def modify_user_info():
    '''
    修改用户信息
    :return:
    '''
    menu = '''-------- 修改用户信息 --------
    1. 调整额度
    2. 冻结账户
    3. 解冻账户
    4. 注销用户
    5. 修改密码
    6. 退出
    '''
    flag = True
    count = 0
    account = input('请输入要修改的账户:').strip()
    account_data = auth.acc_check(account)
    while flag:
        if account_data['user_type'] == 1:
            print('只允许修改普通用户...')
            break
        print(menu)
        if account_data:
            choose = input('请选择操作:').strip()
            if choose == '1':
                credit = input('输入要调整的额度:').strip()
                if credit.isdigit():
                    credit = float(credit)
                    balance = credit - account_data['credit'] + account_data['balance'] # 计算新余额
                    account_data['withdraw'] = (credit - account_data['credit'])/2 + account_data['withdraw'] # 计算新的取款额度
                    account_data['credit'] = credit
                    account_data['balance'] = balance
                    accounts.dump_account(account_data)
                    logger(account, '调整额度为: %s' % credit)
                    print('账户[%s]额度已调整为[￥%s]' % (account,credit))
                else:
                    print('输入的额度类型错误,请输入整数...')
            elif choose == '2':
                account_data['status'] = 1
                accounts.dump_account(account_data)
                logger(account, '账户被冻结')
                print('[%s] 账户已被冻结...' % account)
            elif choose == '3':
                account_data['status'] = 0
                accounts.dump_account(account_data)
                print('[%s] 账户已解冻...' % account)
                logger(account, '账户解除冻结')
            elif choose == '4':
                account_data['status'] = 2
                accounts.dump_account(account_data)
                logger(account, '账户被注销')
                print('[%s] 账户已注销...' % account)
            elif choose == '5':
                while count < 3:
                    old_password = input('请输入原密码:').strip()
                    if old_password == account_data['password']:
                        new_password = input('请输入新密码:').strip()
                        account_data['password'] = new_password
                        accounts.dump_account(account_data)
                        logger(account, '账户修改密码成功')
                        print('[%s] 账户密码已修改成功...' % account)
                        break
                    else:
                        print('原密码错误,请重新输入...')
                    count += 1
            elif choose == '6':
                flag = False
        else:
            print('需要修改的用户[%s]不存在...' % account)

def registered():
    '''
    添加用户
    :param acc_data:
    :return:
    '''
    flag = True
    while flag:
        account = input('[b退出]请输入账号:').strip()
        if account.isdigit() and len(account) == 5:
            is_account = auth.acc_check(account)
            if is_account is None:
                password = input('请输入密码:').strip()
                if password:
                    enroll_date = datetime.datetime.now().strftime('%Y-%m-%d')
                    expire_date = (datetime.datetime.now().replace(datetime.datetime.now().year + 5)
                                   + datetime.timedelta(-1)).strftime('%Y-%m-%d')
                    account_data = {
                        "id": account,
                        "password": password,
                        "credit": 15000,
                        "balance": 15000,
                        'withdraw': 7500,
                        "enroll_date": enroll_date,
                        "expire_date": expire_date,
                        "pay_day": 7,
                        "repay_day": 25,
                        "status": 0,
                        "user_type": 0
                    }
                    accounts.dump_account(account_data)
                    logger(account, '已注册成功')
                    print('[%s]账户已添加成功...' % account)
                    flag = False
                else:
                    print('密码不能为空...')
            else:
                print('[%s]账户已存在...' % account)
        elif account == 'b':
            flag = False
        else:
            print('注册账户请使用五位数字...')

def manager_interactive(acc_data):
    '''
    管理员交互
    :param acc_data:
    :return:
    '''
    menu = '''-------- ATM Admin --------
    1. 查询用户信息
    2. 修改用户信息
    3. 添加账户
    4. 退出
    '''
    menu_dic = {
        '1': query_user_info,
        '2': modify_user_info,
        '3': registered
    }

    flag = True
    while flag:
        print(menu)
        choose = input('请选择:').strip()
        if choose in menu_dic:
            menu_dic[choose]()
        elif choose == '4':
            print('退出 Atm 管理系统!!!')
            flag = False
        else:
            print('您输入的选项不存在...')

def manager_run():
    '''
    管理入口启动时加载此函数,管理用户信息
    :return:
    '''
    acc_data = auth.acc_login(user_data)
    if user_data['is_authenticated']:
        user_data['account_data'] = acc_data
        if acc_data['user_type'] == 0:
            exit('普通用户请运行[atm.py]登录')
        manager_interactive(user_data)
#========================================================================
def interactive(user_data):
    '''
    用户交互函数
    :param user_data: 用户登录后的所有数据
    :return:
    '''
    menu = '''---------- ATM ----------
    1. 账户信息
    2. 还款
    3. 取款
    4. 转账
    5. 账单
    6. 退出
    '''
    menu_dic = {
        '1': account_info,
        '2': repay,
        '3': withdraw,
        '4': transfer,
        '5': bill_check
    }
    flag = True
    while flag:
        print(menu)
        choose = input('请选择操作:').strip()
        if choose in menu_dic:
            menu_dic[choose](user_data)  # 根据用户选择执行不同的函数
        elif choose == '6':
            print('退出ATM系统')
            flag = False
        else:
            print('输入的选项不存在...')

def run():
    '''
    程序启动加载此函数,处理用户交互
    :return:
    '''
    acc_data = auth.acc_login(user_data)
    if user_data['is_authenticated']:
        user_data['account_data'] = acc_data
        if acc_data['user_type'] == 1:
            exit('用户入口,管理员请运行[manager.py]')
        interactive(user_data)  # 用户交互
